package org.geom.curve.selix;

import org.geom.Maths;
import org.geom.Point3D;
import org.geom.Vector3D;
import org.geom.curve.Curve;
import org.geom.curve.ICurve;

public class SElix extends Curve {

	public static String U = "u";
	
	//---------------------------------------------------------------------- class vars
	
	private ICurve trunk;
	
	private float _u = 30f;
	private float _r = 30f;
	private float _k = 30f;
	
	//HashMap<Float, Point3D> points2parameter = new HashMap<Float, Point3D>();
	
	//---------------------------------------------------------------------- contructors
	
	public SElix(ICurve curve) {
		this.setTrunk(curve);
	}

	//---------------------------------------------------------------------- overrides
	
	@Override
	public Point3D sample(float u) {
		Vector3D 		
		n = trunk.normal(u),
		b = trunk.binormal(u), 
		t = trunk.tangent(u);

		Point3D 
		p = trunk.sample(u);
		
		float 
		r = _r,
		k = _k;
		

		//P(t) + rcos(t*l)N(t) + rsen(t*l)B(t) + kT(t)
		
		float l = Maths.PI*_u;
		
		return new Point3D(
				p.x + 
				r*Maths.cos(u*l)*n.x +
				r*Maths.sin(u*l)*b.x + 
				k*u*t.x
				,
				p.y + 
				r*Maths.cos(u*l)*n.y +
				r*Maths.sin(u*l)*b.y + 
				k*u*t.y
				,
				p.z + 
				r*Maths.cos(u*l)*n.z +
				r*Maths.sin(u*l)*b.z  +
				k*u*t.z
				);
	}
	
	@Override
	public float getArc() {
		return trunk.getArc();
	}
	
	//-------------------------------------------------------- foo overrides
	@Override
	public Vector3D derivateI(float t) {
		// TODO : foo		
		
		System.out.println("SElix > derivateI > foo");
		return new Vector3D();
	}
	@Override
	public Vector3D derivateII(float t) {
		// TODO : foo
		System.out.println("SElix > derivateII > foo");
		return new Vector3D();
	}
	
	//-------------------------------------------------------- publics
	//-------------------------------------------------------- getter && setter
	public void setTrunk(ICurve trunk) {
		this.trunk = trunk;
	}

	public ICurve getTrunk() {
		return trunk;
	}

	// TODO : called by controller
	public void setU(float t, boolean increment) {
		if(increment)_u += t;
		else _u=t;
	}
	public float getU() {
		return _u;
	}
	
	public void setR(float t, boolean increment) {
		if(increment)_r += t;
		else _r=t;
	}
	public float getR() {
		return _r;
	}
	
	public void setK(float t, boolean increment) {
		if(increment)_k += t;
		else _k=t;
	}
	public float getK() {
		return _k;
	}

}
